﻿using System;
using System.Collections.Generic;
using System.Web;
using System.IO;
using Ionic.Zip;

namespace CCPSIP
{
    /// <summary>API_069：ERP單據圖片上傳API</summary>
    ///idHeader = 裝置 UUID 前八碼。iOS 請使用 [CCPCrypto getIdHeader] 呼叫。
    ///checkcode = 裝置限時驗證碼。iOS 請使用 [CCPCrypto getCheckcode] 呼叫。
    ///SystemKind = ERP子系統名稱。
    ///KeyNumber = ERP系統紀錄uKey。
    ///上傳檔案 = 圖片集合Zip檔。只允許上傳Zip檔，且只允許解壓縮後的檔案為jpg或jpeg檔案。請直接將多張圖片壓縮成Zip檔且不要將圖片放在目錄下再壓縮。

    public class verify_photo_upload : IHttpHandler
    {
        private string UploadDir = ChrisKit.RootDir + "CCP\\ERP_Photos\\";

        public void ProcessRequest(HttpContext context)
        {
            HttpRequest req = context.Request;
            HttpResponse resp = context.Response;
            resp.ContentType = "text/plain";
            resp.ContentEncoding = System.Text.Encoding.UTF8;
            DateTime reqTime = DateTime.Now;
            string resultStr = "";

            const string UnzipTempFolderRootPath = "C:\\iSenderTempFolder\\";
            string[] AllowedImageType = { ".jpg", ".jpeg" };
            string AllowedZipType = ".zip";

            try
            {
                //【01】取得POST參數，驗證身分
                string idHeader = req.Form["idHeader"];
                string checkcode = req.Form["checkcode"];
                string SystemKind = req.Form["SystemKind"];
                string KeyNumber = req.Form["KeyNumber"];
                string Remark = req.Form["Remark"]; //can be null

                SipUserInfo UserInfo = SipKit.GetUserInfo(idHeader, checkcode, req);
                if (UserInfo == null)
                    throw new Exception("Error_01: Cannot identify this device.");  //無法識別此裝置

                //檢查參數
                if (string.IsNullOrEmpty(SystemKind) || string.IsNullOrEmpty(KeyNumber))
                    throw new Exception("Error_02: Parameter error.");  //有參數為空

                if (req.Files[0].ContentLength == 0)
                    throw new Exception("Error_03: File length error.");    //檔案為空

                if (Path.GetExtension(req.Files[0].FileName).ToLower() != AllowedZipType)
                    throw new Exception("Error_04: Only accept zip file.");    //上傳的檔案不為Zip檔

                if (!UserInfo.UserType.StartsWith("CCP"))
                    throw new Exception("Error_05: Not a CCP employee.");   //使用者不為長春員工

                //【02】檢查是否已有相同紀錄(SystemKind和uKey已存在)
                if (OracleErpKit.HasPhotoRecord(SystemKind, KeyNumber))
                    OracleErpKit.DeletePhotoRecord(SystemKind, KeyNumber);

                //【03】檢查根暫存資料夾是否存在
                if (!Directory.Exists(UnzipTempFolderRootPath))
                    Directory.CreateDirectory(UnzipTempFolderRootPath);

                //【04-1】解壓縮Zip檔至暫存資料夾
                String NewGuid = Convert.ToString(Guid.NewGuid());

                string UnzipTempFolderPath = UnzipTempFolderRootPath + "\\" + NewGuid;
                if (!Directory.Exists(UnzipTempFolderPath))
                    Directory.CreateDirectory(UnzipTempFolderPath);

                //將收到的zip檔儲存到暫存目錄下
                string TempFileName = NewGuid + ".zip";
                req.Files[0].SaveAs(UnzipTempFolderPath + "\\" + TempFileName);

                using (ZipFile TempZipFile = new ZipFile(UnzipTempFolderPath + "\\" + TempFileName, System.Text.Encoding.Default))
                {
                    TempZipFile.ExtractAll(UnzipTempFolderPath, ExtractExistingFileAction.OverwriteSilently);
                }
                if (Directory.GetFiles(UnzipTempFolderPath).Length == 1)    //解壓縮後只剩原本.ZIP檔在暫存目錄下
                    throw new Exception("Error_06: No file in the zip file.");

                //【04-2】備份Zip檔至Unicode_db
                string BackupPath = UploadDir + SystemKind + "\\" + KeyNumber;
                if (!Directory.Exists(BackupPath))
                    Directory.CreateDirectory(BackupPath);

                req.Files[0].SaveAs(BackupPath + "\\" + UserInfo.PPS_CODE + "_" + UserInfo.SIP_Num + "_" + DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss") + ".zip");

                //刪除原Zip檔, 使目錄中只剩下解壓縮後的圖片檔案
                File.Delete(UnzipTempFolderPath + "\\" + TempFileName);

                //【05】將參數與解壓後的圖片存入Oracle
                string[] UnZipFiles = Directory.GetFiles(UnzipTempFolderPath);

                //先檢查解壓縮後的圖片檔名
                foreach (string file in UnZipFiles)
                {
                    bool AllowFile = false;
                    foreach (string extension in AllowedImageType)
                    {
                        if (Path.GetExtension(file).ToLower() == extension)
                            AllowFile = true;
                    }

                    if (!AllowFile)
                        throw new Exception("Error_07: Image file error. Only accept jpg or jpeg file.");
                }

                //將資料寫入Oracle
                OracleErpKit.InsertPhotoRecordWrapper(SystemKind, KeyNumber, UnZipFiles, UserInfo.PPS_CODE, Remark);

                //【06】刪除暫存目錄與檔案
                if (Directory.Exists(UnzipTempFolderPath))
                    Directory.Delete(UnzipTempFolderPath, true);

                //【99】回傳結果
                string ReturnObject = "OK";
                resp.ContentType = "application/json";
                resp.Charset = null;
                fastJSON.JSON.Instance.Parameters.EnableAnonymousTypes = true;
                resultStr = fastJSON.JSON.Instance.ToJSON(ReturnObject);
            }
            catch (Exception ex)
            {
                resp.ContentType = "application/xml";
                resultStr = ChrisKit.Ex2Xml(ex, false);
            }
            finally
            {
                int contentLength = resp.ContentEncoding.GetByteCount(resultStr);
                resp.AppendHeader("Content-Length", contentLength.ToString());
                resp.Write(resultStr);
                resp.Flush();
                resp.Close();
            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}